package com.market.domain;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.Table;
import javax.persistence.Transient;

@Entity
@Table(name = "orderdetail")
public class OrderDetail extends BaseObject {

	/**
	 * 
	 */
	private static final long serialVersionUID = -3098696556150640746L;

	@Override
	public boolean equalsId(Object o) {
		if (o instanceof OrderDetail && ((OrderDetail) o).getId().equals(id)) {
			return true;
		}
		return false;
	}

	/**
	 * Return if confirmed quantity is more than one， then will be marked yellow
	 * when prepare this order
	 * 
	 * @param confirmedQuantity
	 */
	public Boolean getIsConfirmedQuantityMoreThanOne() {
		if (this.confirmedQuantity > 1) {
			return Boolean.TRUE;
		}
		return Boolean.FALSE;
	}

	@Transient
	public Double getOrderedGST() {
		// if (this.product.getIsTaxable()) {
		return this.getOrderedSubTotal() * this.gstRate;
		// }
		// return 0D;

	}

	@Transient
	public Double getOrderedQST() {
		// if (this.product.getIsTaxable()) {
		return this.getOrderedSubTotal() * this.qstRate;
		// }
		// return 0D;
	}

	@Transient
	public Double getOrderedSubTotal() {
		// This need * specification, because orderedQuantity is base on
		// stockUnit, but orderedPrice is base on priceUnit.
		// eg. orderedQuantity is 3pcs and orderedPrice is $1.50/lb and each pc
		// is around 0.8lb, so the total would be around 3pcs * $1.50 * 0.8=$3.6
		return this.orderedQuantity * this.specification * this.orderedPrice;
	}

	@Transient
	public Double getOrderedSubTotalPlusTax() {
		return this.getOrderedSubTotal() + this.getOrderedGST()
				+ this.getOrderedQST();
	}

	@Transient
	public Double getConfirmedGST() {
		return this.getConfirmedSubTotal() * this.gstRate;
	}

	@Transient
	public Double getConfirmedQST() {
		return this.getConfirmedSubTotal() * this.qstRate;
	}

	@Transient
	public Double getConfirmedSubTotal() {
		// This need * specification, because orderedQuantity is base on
		// stockUnit, but orderedPrice is base on priceUnit.
		// eg. orderedQuantity is 3pcs and orderedPrice is $1.50/lb and each pc
		// is around 0.8lb, so the total would be around 3pcs * $1.50 * 0.8=$3.6
		return this.confirmedQuantity * this.specification
				* this.getConfirmedPrice();
	}

	@Transient
	public Double getConfirmedSubTotalPlusTax() {
		return this.getConfirmedSubTotal() + this.getConfirmedGST()
				+ this.getConfirmedQST();
	}

	@Transient
	public Double getDeliveredGST() {
		// if (this.product.getIsTaxable()) {
		return this.getDeliveredSubTotal() * this.gstRate;
		// }
		// return 0D;
	}

	public Double getDeliveredQST() {
		// if (this.product.getIsTaxable()) {
		return this.getDeliveredSubTotal() * this.qstRate;
		// }
		// return 0D;
	}

	@Transient
	public Double getDeliveredSubTotal() {
		// This don't need * specification, because the deliveredQuantity is the
		// exact quantity we put in package.
		return this.deliveredQuantity * this.deliveredPrice;
	}

	@Transient
	public Double getDeliveredSubTotalPlusTax() {
		return this.getDeliveredSubTotal() + this.getDeliveredGST()
				+ this.getDeliveredQST();
	}

	@Transient
	public Boolean getIsTaxable() {
		return this.gstRate > 0D || this.qstRate > 0D;
	}

	// public void setOrderedQuantityToConfirmedQuantity(Integer
	// orderedQuantity) {
	// this.confirmedQuantity = orderedQuantity;
	// }

	/*
	 * This method have to * specification, because confirmedQuantity use
	 * stockUnit, but deliveredQuantity use priceUnit.
	 */
	// public void setConfirmedQuantityToDeliveredQuantity(
	// Integer confirmedQuantity) {
	// // This have to * specification, because confirmedQuantity use
	// // stockUnit, but deliveredQuantity use priceUnit.
	// this.setDeliveredQuantity(confirmedQuantity *
	// this.product.getSpecification());
	// }

	@Transient
	private Long deliveredQuantityInGram = 0L;

	public Long getDeliveredQuantityInGram() {
		return deliveredQuantityInGram;
	}

	public void setDeliveredQuantityInGram(Long deliveredQuantityInGram) {
		this.deliveredQuantityInGram = deliveredQuantityInGram;
		this.deliveredQuantity = this.deliveredQuantityInGram / 454D;
	}

	@Id
	@GeneratedValue(strategy = GenerationType.AUTO)
	private Long id = 0L;

	// @ManyToOne(fetch = FetchType.LAZY)
	// @JoinColumn(name="order_id",nullable=false)
	// private Order order;
	@ManyToOne(fetch = FetchType.EAGER)
	@JoinColumn(name = "product_id", nullable = false)
	private Product product;
	@Column(columnDefinition = "Double default 1")
	private Double specification = 1D;
	@Column
	private Integer orderedQuantity = 1;
	@Column(columnDefinition = "Double default 0")
	private Double orderedPrice = 0D;
	@Column
	private Integer confirmedQuantity = 0;
	@Column
	private Double confirmedPrice = 0D;
	@Column
	private Double deliveredQuantity = 0D;

	@Column(columnDefinition = "Double default 0")
	private Double deliveredPrice = 0D;

	@Column(columnDefinition = "Double default 0")
	private Double gstRate = 0D; // The rate that the customer has paid for this
									// order, Maybe different at at different
									// time for the same product.
	@Column(columnDefinition = "Double default 0")
	private Double qstRate = 0D; // The rate that the customer has paid for this
									// order, Maybe different at at different
									// time for the same product.

	public Long getId() {
		return id;
	}

	public void setId(Long id) {
		this.id = id;
	}

	public Product getProduct() {
		return product;
	}

	public void setProduct(Product product) {
		this.product = product;
	}

	public Double getSpecification() {
		return specification;
	}

	public void setSpecification(Double specification) {
		this.specification = specification;
	}

	public Integer getOrderedQuantity() {
		return orderedQuantity;
	}

	public void setOrderedQuantity(Integer orderedQuantity) {
		this.orderedQuantity = orderedQuantity;
	}

	public Integer getConfirmedQuantity() {
		return confirmedQuantity;
	}

	public void setConfirmedQuantity(Integer confirmedQuantity) {
		this.confirmedQuantity = confirmedQuantity;
	}

	public Double getConfirmedPrice() {
		return confirmedPrice;
	}

	public void setConfirmedPrice(Double confirmedPrice) {
		this.confirmedPrice = confirmedPrice;
	}

	public Double getDeliveredQuantity() {
		return deliveredQuantity;
	}

	public void setDeliveredQuantity(Double deliveredQuantity) {
		this.deliveredQuantity = deliveredQuantity;
		this.deliveredQuantityInGram = Math.round(this.deliveredQuantity * 454);
	}

	public Double getOrderedPrice() {
		return orderedPrice;
	}

	public void setOrderedPrice(Double orderedPrice) {
		this.orderedPrice = orderedPrice;
	}

	public Double getDeliveredPrice() {
		return deliveredPrice;
	}

	public void setDeliveredPrice(Double deliveredPrice) {

		this.deliveredPrice = deliveredPrice;
	}

	public Double getGstRate() {
		return gstRate;
	}

	public void setGstRate(Double gstRate) {
		this.gstRate = gstRate;
	}

	public Double getQstRate() {
		return qstRate;
	}

	public void setQstRate(Double qstRate) {
		this.qstRate = qstRate;
	}

	@Override
	public String toString() {
		return "OrderDetail [id=" + id + ", orderedQuantity=" + orderedQuantity
				+ ", deliveredQuantity=" + deliveredQuantity
				+ ", orderedPrice=" + orderedPrice + ", deliveredPrice="
				+ deliveredPrice + "]";
	}

	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime * result
				+ ((deliveredPrice == null) ? 0 : deliveredPrice.hashCode());
		result = prime
				* result
				+ ((deliveredQuantity == null) ? 0 : deliveredQuantity
						.hashCode());
		result = prime * result
				+ ((orderedPrice == null) ? 0 : orderedPrice.hashCode());
		result = prime * result
				+ ((orderedQuantity == null) ? 0 : orderedQuantity.hashCode());
		return result;
	}

	@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (getClass() != obj.getClass())
			return false;
		OrderDetail other = (OrderDetail) obj;
		if (deliveredPrice == null) {
			if (other.deliveredPrice != null)
				return false;
		} else if (!deliveredPrice.equals(other.deliveredPrice))
			return false;
		if (deliveredQuantity == null) {
			if (other.deliveredQuantity != null)
				return false;
		} else if (!deliveredQuantity.equals(other.deliveredQuantity))
			return false;
		if (orderedPrice == null) {
			if (other.orderedPrice != null)
				return false;
		} else if (!orderedPrice.equals(other.orderedPrice))
			return false;
		if (orderedQuantity == null) {
			if (other.orderedQuantity != null)
				return false;
		} else if (!orderedQuantity.equals(other.orderedQuantity))
			return false;
		return true;
	}

}
